﻿using Pdf2epub.BusinessLogic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

namespace Pdf2epub.Epub
{
    internal static class ChapterHelpers
    {
        public static SubChapter CreateChapterFromHtmlHeader(XmlNode headerNode)
        {
            XmlElement anchorNode = FíndXmlNode("a", headerNode.ChildNodes) as XmlElement;
            XmlElement spanNode = FíndXmlNode("span", headerNode.ChildNodes) as XmlElement;

            if ((anchorNode != null) && (spanNode != null))
            {
                string anchorId = anchorNode.GetAttribute("id");
                string headerName = spanNode.InnerText.Trim();
                return new SubChapter(headerName, anchorId);
            }
            return null;
        }

        public static IEnumerable<SubChapter> FindChapters(string chapterFile, int largesttHeaderSize, int smallestHeaderSize)
        {
            List<SubChapter> subChapters = new List<SubChapter>();

            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(chapterFile);

            XmlNode htmlNode = FíndXmlNode("html", xmlDocument.ChildNodes);
            if (htmlNode != null)
            {
                XmlNode bodyNode = FíndXmlNode("body", htmlNode.ChildNodes);
                if (bodyNode != null)
                {
                    IEnumerable<XmlNode> headerNodes = FindHeaderNodes(largesttHeaderSize, smallestHeaderSize, bodyNode.ChildNodes);
                    subChapters.AddRange(headerNodes.Select(CreateChapterFromHtmlHeader).Where(newChapter => newChapter != null));
                }
            }
            return subChapters;
        }

        public static string FindFirstH1Title(string filePath)
        {
            IEnumerable<SubChapter> chapters = FindChapters(filePath, 1, 1);
            foreach (var chapter in chapters)
            {
                return (chapter.Title);
            }
            return string.Empty;
        }

        public static IEnumerable<XmlNode> FindHeaderNodes(int headerStartId, int headerEndId, XmlNodeList childNodes)
        {
            List<string> headerTypes = new List<string>();
            for (int i = headerStartId; i <= headerEndId; i++)
            {
                headerTypes.Add(string.Format("h{0}", i));
                headerTypes.Add(string.Format("H{0}", i));
            }
            return childNodes.Cast<XmlNode>().Where(node => headerTypes.Contains(node.Name)).ToArray();
        }

        public static XmlNode FíndXmlNode(string nodeName, XmlNodeList childNodes)
        {
            return childNodes.Cast<XmlNode>().FirstOrDefault(node => node.Name.Equals(nodeName, StringComparison.InvariantCultureIgnoreCase));
        }
    }
}